<?php

namespace App\Console;

use App\Common\Constant\CacheKey;
use App\Common\Constant\Params;
use App\Console\Commands\generateProvince;
use App\Console\Commands\importGoods;
use App\Console\Commands\importMaster;
use App\Console\Commands\importMerchant;
use App\Console\Commands\importOrder;
use App\Console\Commands\repairMaster;
use App\Console\Commands\repairOrder;
use App\Events\OrderSuccess;
use App\Models\Master;
use App\Models\Order;
use App\Models\OrderRefund;
use App\Models\OrderStatus;
use App\Services\ICacheService;
use App\Services\Impl\EvaluateServiceImpl;
use App\Services\IOrderService;
use App\Services\IRefundService;
use Cache;
use Carbon\Carbon;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Collection;
use Log;

class Kernel extends ConsoleKernel
{

    private $cacheService;
    private $refundService;
    private $orderService;
    private $evaluateService;

    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        importMaster::class,
        importOrder::class,
        importMerchant::class,
        importGoods::class,
        repairOrder::class,
        repairMaster::class,
        generateProvince::class,
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $logfile = storage_path('logs/schedule-'.date('Y-m-d').'.log');
        $this->cacheService = resolve(ICacheService::class);
        $this->refundService = resolve(IRefundService::class);
        $this->orderService = resolve(IOrderService::class);
        $this->evaluateService = resolve(EvaluateServiceImpl::class);

        /**
         * 临时停单恢复
         */
        $schedule->call(function () {
            $msg = "Begin 临时停单恢复\n";
            echo $msg;
            Log::debug($msg);

            $masters = Master::where('status',Params::USER_STATUS_STOP)->whereNotEmpty('disable_time')->get();
            if (!$masters->count()){
                return;
            }
            $master_ids = [];
            $weixin_userids = [];
            $masters->each(function ($item, $key) use (&$master_ids,&$weixin_userids){
                if (Carbon::now()->gt($item->disable_time)) {
                    $master_ids[] = $item->id;
                    $weixin_userids[] = $item->weixin_userid;
                }
            });
            if (empty($master_ids)){
                return;
            }

            $msg = 'Going to recover '.count($master_ids).' masters, master_ids: '.implode(',',$master_ids)."\n";
            echo $msg;
            Log::debug($msg);
            $success_count = Master::whereIn('id',$master_ids)->update(['status'=>Params::USER_STATUS_NORMAL,'disable_time'=>null])
            && Collection::make($weixin_userids)->each(function ($item, $key){
                $this->cacheService->del(CacheKey::currentUserKey($item));
            });
            $msg = 'Recoverd '.$success_count.' masters'."\n";
            echo $msg;
            Log::debug($msg);
        })->name('临时停单恢复')->hourly()->appendOutputTo($logfile);

        /**
         * 订单完成超时未确认将自动付款到账
         */
        $schedule->call(function () {
            $msg = "Begin 订单完成超时未确认将自动付款到账\n";
            echo $msg;
            Log::debug($msg);

            $orders = OrderStatus::where('master_status',Params::ORDER_MASTER_STATUS_FINISHED)->whereEmpty('order_success_time')->get();
            if (!$orders->count()){
                return;
            }
            $order_ids = [];
            $orders->each(function ($item, $key) use (&$order_ids){
                if (Carbon::now()->gt($item->finish_time->addDays(config('common.auto_pay_days')))) {
                    $order_ids[] = $item->order_id;
                }
            });
            if (empty($order_ids)){
                return;
            }

            $msg = 'Going to pay '.count($order_ids).' orders, order_ids: '.implode(',',$order_ids)."\n";
            echo $msg;
            Log::debug($msg);
            $success_count = 0;
            Collection::make($order_ids)->each(function ($item, $key) use (&$success_count){
                event(new OrderSuccess($item)) ? $success_count++ : null;
            });
            $msg = 'Paid '.$success_count.' orders'."\n";
            echo $msg;
            Log::debug($msg);
        })->name('订单完成超时未确认将自动付款到账')->hourly()->appendOutputTo($logfile);

        /**
         * 报价截止后，未雇佣付款订单在限定时间后将自动关闭
         */
        $schedule->call(function () {
            $msg = "Begin 报价截止后，未雇佣付款订单在限定时间后将自动关闭\n";
            echo $msg;
            Log::debug($msg);

            $orders = Order::whereEmpty('pay_time')->with(['status'])->get();
            if (!$orders->count()){
                return;
            }

            $order_ids = [];
            $orders->each(function ($item, $key) use (&$order_ids){
                if (!$item->status || ($item->status->except_status == Params::ORDER_EXCEPT_CANCELED)){
                    return;
                }
                if (Carbon::now()->gt($item->add_time->addDays(config('common.order_offering_endtime'))->addDays(config('common.order_auto_close_days')))) {
                    $order_ids[] = $item->id;
                }
            });
            if (empty($order_ids)){
                return;
            }

            $msg = 'Going to cancel '.count($order_ids).' orders, order_ids: '.implode(',',$order_ids)."\n";
            echo $msg;
            Log::debug($msg);
            $success_count = 0;
            Collection::make($order_ids)->each(function ($item, $key) use (&$success_count){
                $this->orderService->cancel($item) ? $success_count++ : null;
            });
            $msg = 'Canceled '.$success_count.' orders'."\n";
            echo $msg;
            Log::debug($msg);
        })->name('报价截止时间内未雇佣付款订单将自动关闭')->hourly()->appendOutputTo($logfile);

        /**
         * 退款申请时间内未处理系统将自动默认退款给下单用户
         */
        $schedule->call(function () {
            $msg = "Begin 退款申请时间内未处理系统将自动默认退款给下单用户\n";
            echo $msg;
            Log::debug($msg);

            $refunds = OrderRefund::whereEmpty('refund_result_type')->whereEmpty('refund_success_time')->get();
            if (!$refunds->count()){
                return;
            }

            $refund_ids = [];
            $refunds->each(function ($item, $key) use (&$refund_ids){
                if (Carbon::now()->gt($item->add_time->addDays(config('common.auto_refund_days')))) {
                    $refund_ids[] = $item->id;
                }
            });
            if (empty($refund_ids)){
                return;
            }

            $msg = 'Going to refund '.count($refund_ids).' orders, refund_ids: '.implode(',',$refund_ids)."\n";
            echo $msg;
            Log::debug($msg);
            $success_count = 0;
            Collection::make($refund_ids)->each(function ($item, $key) use (&$success_count){
                $this->refundService->agreeRefund($item) ? $success_count++ : null;
            });
            $msg = 'Refund '.$success_count.' orders'."\n";
            echo $msg;
            Log::debug($msg);
        })->name('退款申请时间内未处理系统将自动默认退款给下单用户')->hourly()->appendOutputTo($logfile);

        //
        $schedule->call(function () {
            $msg = "Begin 订单完成超时未评价师傅自动默认好评\n";
            echo $msg;
            Log::debug($msg);

            $orders = OrderStatus::where('evaluate_status',Params::ORDER_EVALUATE_NOTYET)->whereNotEmpty('finish_time')->get();
            echo $orders->count();
            Log::debug($orders->count());
            if (!$orders->count()){
                return;
            }
            $order_ids = [];
            $orders->each(function ($item, $key) use (&$order_ids){
                if (Carbon::now()->gt($item->finish_time->addDays(config('common.order_evaluate_days')))) {
                    $order_ids[] = $item->order_id;
                }
            });
            if (empty($order_ids)){
                return;
            }

            $msg = 'Going to evluate '.count($order_ids).' evluate, order_ids: '.implode(',',$order_ids)."\n";
            echo $msg;
            Log::debug($msg);
            $success_count = 0;
            Collection::make($order_ids)->each(function ($item, $key) use (&$success_count){
                $this->evaluateService->evaluateMaster($item)?$success_count++:null;
            });
            $msg = 'Evluate '.$success_count.' orders'."\n";
            echo $msg;
            Log::debug($msg);
        })->name('订单完成超时未评价师傅自动默认好评')->hourly()->appendOutputTo($logfile);

    }

    /**
     * Register the Closure based commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        require base_path('routes/console.php');
    }
}
